package com.easybuilder.blog.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.easybuilder.blog.dao.BlogArticleDao;
import com.easybuilder.blog.dto.ArticleDTO;
import com.easybuilder.blog.entity.Article;
import com.easybuilder.blog.entity.ArticleCriteria;
import com.easybuilder.blog.entity.BlogFans;
import com.easybuilder.blog.entity.BlogLikes;
import com.easybuilder.blog.service.ArticleService;
import com.easybuilder.blog.service.FansService;
import com.easybuilder.blog.service.LikesService;
import com.easybuilder.common.base.entity.Page;
import com.easybuilder.common.enums.PageType;
import com.easybuilder.common.utils.StringUtil;
import com.easybuilder.common.utils.TimeUtil;
import com.easybuilder.common.utils.UserUtil;
import com.easybuilder.core.rbac.entity.SysUser;
import com.easybuilder.core.rbac.service.SysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ArticleServiceImpl implements ArticleService {

    @Resource
    private BlogArticleDao blogArticleDao;
    @Autowired
    private LikesService likesService;
    @Autowired
    private SysUserService userService;
    @Autowired
    private FansService fansService;

    @Override
    public Article publish(Article article) {
        //TODO 需要根据当前登录人信息，设置文章发布人
        SysUser user = UserUtil.getUser();
        if (user != null) {
            article.setCreateUserId(user.getId());
            article.setCreateNickname(user.getNickname());
        }
        // 设置发布时间
        article.setCreateTime(new Date());

        blogArticleDao.insertSelective(article);
        return article;
    }

    /** 条件查询单条文章 */
    @Override
    public Article selectOneByExample(Example example) {
        return blogArticleDao.selectOneByExample(example);
    }

    @Override
    public Page<ArticleDTO> page(int pageNum, int pageSize, ArticleCriteria articleCriteria) {
        StringBuilder andSql = new StringBuilder();
        // 有效状态
        andSql.append(" and available = 1 ");
        // 分类
        if (StringUtil.isNotEmpty(articleCriteria.getCategory())) {
            andSql.append(" and category = '").append(articleCriteria.getCategory()).append("' ");
        }
        // 标题
        if (StringUtil.isNotEmpty(articleCriteria.getTitle())) {
            andSql.append(" and title like '%").append(articleCriteria.getTitle()).append("%' ");
        }
        // 如果是B端管理页面，需要查询当前登陆人自己的文章；后续会根据角色进行调整
        if (PageType.B.name().equals(articleCriteria.getPageType())) {
            SysUser user = UserUtil.getUser();
            Long userId = null;
            if (user != null) {
                userId = user.getId();
            }
            andSql.append(" and create_user_id = '").append(userId).append("'");
        }
        // 数据总量
        int total = blogArticleDao.countByAndSql(andSql.toString());
        andSql.append(" order by create_time desc");
        andSql.append(" limit ").append(pageNum*pageSize).append(",").append(pageSize);
        List<Article> articles = blogArticleDao.selectByAndSql(andSql.toString());
        // 转换为DTO
        List<ArticleDTO> result = new ArrayList<>();
        if (articles != null && articles.size() > 0) {
            for (Article article : articles) {
                ArticleDTO articleDTO = new ArticleDTO();
                BeanUtils.copyProperties(article, articleDTO);
                result.add(articleDTO);
            }
        }
        // 设置文章相关的其他参数：例如当前用户是否已经点赞等
        setOtherParams(result);
        return new Page<ArticleDTO>(Long.valueOf(total), result);
    }


    /** 条件查询数据总量 **/
    @Override
    public int getTotal(ArticleCriteria articleCriteria) {
        Example example = new Example(Article.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtil.isNotEmpty(articleCriteria.getCategory())) {
            criteria.andCondition("and category = " + articleCriteria.getCategory());
        }
        return 0;
    }

    /** 批量删除 */
    @Override
    public int batchDelete(List<Long> ids) {
        Long userId = null;
        String nickname = "";
        SysUser user = UserUtil.getUser();
        if (user != null) {
            userId = user.getId();
            nickname = user.getNickname();
        }
        String idstr = ids.stream().map(item -> {
            return String.valueOf(item);
        }).collect(Collectors.joining(","));
        return blogArticleDao.batchDelete(idstr, userId, nickname);
    }

    /** 统计数量 */
    @Override
    public List<Integer> countArticle() {
        return blogArticleDao.countArticle(TimeUtil.getFormatDay(new Date()));
    }

    @Override
    public ArticleDTO getArticleById(Long id) {
        Example example = new Example(Article.class);
        example.createCriteria().andEqualTo("id", id);
        Article article = this.selectOneByExample(example);
        ArticleDTO articleDTO = new ArticleDTO();
        if (article != null) {
            BeanUtils.copyProperties(article, articleDTO);

           SysUser user = userService.getUserById(article.getCreateUserId());
            if (user != null) {
                // 设置文章发布人头像
                articleDTO.setCreateUserImg(user.getImg());
                // 设置当前登录人是否已关注作者
                setAttentionFlag(articleDTO, user);
            }
        }
        return articleDTO;
    }

    /** 统计当前登录用户作品总量 */
    @Override
    public Long countArticleByUserId(Long userId) {
        Long worksCount = blogArticleDao.countArticleByUserId(userId);
        return worksCount;
    }

    /** 设置当前登录人对文章作者的关注标识 */
    private void setAttentionFlag(ArticleDTO articleDTO, SysUser user) {
        // 设置当前登陆人是否已关注当前作者
        SysUser currentUser = UserUtil.getUser();
        if (currentUser != null) {
            Example example = new Example(BlogFans.class);
            example.createCriteria().andEqualTo("fansId", currentUser.getId()).andEqualTo("attentionId", user.getId()).andEqualTo("dropStatus",0);
            List<BlogFans> list = fansService.selectByExample(example);
            if (list != null && list.size() > 0) {
                articleDTO.setAttentioned(true);
            } else {
                articleDTO.setAttentioned(false);
            }
        }
    }


    /** 设置文章相关的其他参数*/
    private void setOtherParams(List<ArticleDTO> articles) {
        if (articles != null && articles.size() > 0) {
            // 获取并设置作品的点赞数据量
            setLikesAndDislikes(articles);
            // 设置登录用户对作品的点赞状态
            setLikeStatus(articles);
            // 设置发布人头像地址
            setCreateUserImg(articles);
        }

     }

    /** 设置发布人头像 */
    private void setCreateUserImg(List<ArticleDTO> articles) {
        List<Long> userIds = articles.stream().map(article -> article.getCreateUserId()).collect(Collectors.toList());
        List<SysUser> sysUsers = userService.selectByUserIds(userIds);
        for (ArticleDTO article : articles) {
            for (SysUser user : sysUsers) {
                if (user.getId().equals(article.getCreateUserId())) {
                    article.setCreateUserImg(user.getImg());
                }
            }
        }
    }

    /** 获取并设置作品的点赞数据量
      * @param articles*/
    private void setLikesAndDislikes(List<ArticleDTO> articles) {
        String articleIds = articles.stream().map(article -> String.valueOf(article.getId())).collect(Collectors.joining(","));
        List<JSONObject> list = likesService.batchSumLikes(0, articleIds);
        if (list != null && list.size() > 0) {
            for (JSONObject item : list) {
                for (ArticleDTO article : articles) {
                    if (item.getInteger("articleId").intValue() == article.getId().intValue()) {
                        article.setLikes(item.getInteger("likes"));
                        article.setDislikes(item.getInteger("dislikes"));
                    }
                }
            }
        }
    }

    /** 设置当前登录用户对作品的点赞状态
     * @param articles*/
    private void setLikeStatus(List<ArticleDTO> articles) {
        // 获取当前登录用户信息
        SysUser user = UserUtil.getUser();
        if (user == null) {
            // 如果当前登录用户信息为空，直接返回
            return;
        }
        // 文章ids
        List<String> articleIds = articles.stream().map(item -> String.valueOf(item.getId())).collect(Collectors.toList());
        Long userId = user.getId();
        Example example = new Example(BlogLikes.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andIn("articleId", articleIds);
        List<BlogLikes> blogLikes = likesService.selectByExample(example);
        for (BlogLikes blogLike : blogLikes) {
            for (ArticleDTO article : articles) {
                if (blogLike.getArticleId().equals(article.getId())) {
                    article.setLikeStatus(blogLike.getStatus());
                }
            }
        }
    }
}
